package online.inote.dic.service.base;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;

import org.apache.commons.lang3.StringUtils;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import tk.mybatis.mapper.code.Style;
import tk.mybatis.mapper.entity.Config;
import tk.mybatis.mapper.util.StringUtil;
import tk.mybatis.spring.mapper.SpringBootBindUtil;

/**
 * @description: 排序
 * @author XQF.Sui
 * @created 2019年4月11日 下午10:52:12
 * @version 1.0
 */
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Sorts implements EnvironmentAware {
	
	private static Style style = Style.camelhump;
	
	private List<String> sorts;
	private Map<String, String> columnMap;
	
	public static  Sorts create(Class<?> clazz) {
		return new Sorts(new ArrayList<String>(), getColumn(clazz));
	}
	
	public Sorts sort(String property, Direction direction) {
		
		if (columnMap.containsKey(property)) {
			sorts.add(columnMap.get(property) + direction.getValue());
		} else {
			sorts.add(property + direction.getValue());
		}
		
		return this;
	}
	
	private static Map<String, String> getColumn(Class<?> clazz) {
		
		Map<String, String> map = new HashMap<>();
		
		Field[] fields = clazz.getDeclaredFields();
		
		for (Field field : fields) {
			if (!Modifier.isStatic(field.getModifiers())) {
				Column column = field.getAnnotation(Column.class);
				
				if (StringUtils.isBlank(column.name())) {
					map.put(field.getName(), StringUtil.convertByStyle(field.getName(), style));
				} else {
					map.put(field.getName(), column.name());
				}
			}
		}
		
		return map;
	}
	
	public String toSqlString() {
		return StringUtils.join(sorts);
	}
	
	@Override
	public void setEnvironment(Environment environment) {
		Config config = SpringBootBindUtil.bind(environment, Config.class, Config.PREFIX);
        if(config != null){
        	style = config.getStyle();
        }
	}
	
	@Getter
	public enum Direction {
		
		ASC, DESC;
		
		public String getValue() {
			return ASC.equals(this) ? " ASC" : " DESC";
		}
	}
}